﻿using Avalon.Core.Data;
using Avalon.Core.Providers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Avalon.Core.MVC.Helpers
{
    public class GridHelper
    {
        public MvcHtmlString Render(HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewData.Model == null) return new MvcHtmlString("No items in the collection.");

            //Get an instace of the meta data provider
            ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => htmlHelper.ViewData.Model, htmlHelper.ViewData.Model.GetType());
            if (modelMetadata.IsCollectionProperty())
            {
                ReferencedCollection collection = new ReferencedCollection((IEnumerable<IEntity>)htmlHelper.ViewData.Model) { AllowAdd = true, AllowDelete = false };
                return Render(collection);
            }
            throw new Exception("Only collections can be rendered as a grid or table.");
        }

        public MvcHtmlString Render(ReferencedCollection collection)
        {
            ///Get an instace of the meta data provider
            return renderTable(collection);
        }

        private static MvcHtmlString renderTable(ReferencedCollection collection)
        {
            //The string builder
            StringBuilder builder = new StringBuilder();

            //The model metadata
            ModelMetadata modelMetadata = collection.CreateModelMetadata();

            IEntityDescriptor descriptor = ContextProvider.ControllerDescriptor.EntityDescriptor;
            if (descriptor != null) {
                builder.AppendFormat("<h2>{0}</h2>", descriptor.Name);
                builder.AppendFormat("<p>{0}</p>", descriptor.Information);
            }
            else {
                builder.AppendFormat("<h1>{0} details</h1>", modelMetadata.GetTitle());
            }

            if (collection.AllowAdd) builder.AppendFormat("<td><a href='{0}' class='btn'>Add</a></td>", modelMetadata.GetEntityCreateUrl(collection.Parent));

            //Begin table
            builder.AppendFormat("<div class='data-table-container'><table class='data-table'>{0}", Environment.NewLine);

            //Create header
            builder.AppendFormat("<thead><tr>");
            foreach (var property in modelMetadata.Properties.Where(p => p.IsSimpleProperty() && p.ShowForDisplay).OrderBy(p => p.Order))
            {
                builder.AppendFormat("<th>{0}</th>", property.GetTitle());
            }
            builder.AppendFormat("</tr></thead>");

            //Create footer
            int columnCount = modelMetadata.Properties.Where(p => p.IsSimpleProperty() && p.ShowForDisplay).Count();
            builder.AppendFormat("<tfoot><tr>");
            builder.AppendFormat("<th colspan='{0}'>total: {1}</th>{2}", columnCount, collection.Count, Environment.NewLine);
            builder.AppendFormat("</tr></tfoot>");

            //Create rows
            builder.AppendFormat("<tbody>");
            foreach (var entity in collection)
            {
                ModelMetadata entityMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => entity, collection.CollectionType);
                builder.AppendFormat("<tr>");
                foreach (var property in entityMetadata.Properties.Where(p => p.IsSimpleProperty() && p.ShowForDisplay).OrderBy(p => p.Order))
                {
                    if (property.IsNavigationProperty())
                    {
                        builder.AppendFormat("<td><a href='{0}'>{1}</a></td>", entityMetadata.GetEntityDetailUrl(), property.Model);
                    }
                    else
                    {
                        builder.AppendFormat("<td>{0}</td>", property.Model);
                    }
                }
                builder.AppendFormat("</tr>{0}", Environment.NewLine);

            }
            builder.AppendFormat("</tbody>");
            builder.AppendFormat("</table></div>");

            return new MvcHtmlString(builder.ToString());
        }
    }
}
